package com.base.cn.platform.os.controller.course.catalog;

import com.base.cn.platform.os.common.controller.BaseController;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.FileExportImportUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.course.CourseType;
import com.base.cn.platform.os.common.utils.file.FileDownloadUtil;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.course.catalog.CourseCatalog;
import com.base.cn.platform.os.entity.course.catalog.CourseCatalogCondition;
import com.base.cn.platform.os.entity.course.comment.CourseComment;
import com.base.cn.platform.os.entity.course.cou.Course;
import com.base.cn.platform.os.entity.course.cou.buy.CourseBuyRecord;
import com.base.cn.platform.os.entity.course.cou.packageCou.PackageCourse;
import com.base.cn.platform.os.entity.course.mould.CouMould;
import com.base.cn.platform.os.entity.course.open.CourseOpen;
import com.base.cn.platform.os.service.course.catalog.CourseCatalogBiz;
import com.base.cn.platform.os.service.course.comment.CourseCommentBiz;
import com.base.cn.platform.os.service.course.cou.CourseBiz;
import com.base.cn.platform.os.service.course.cou.buy.CourseBuyRecordBiz;
import com.base.cn.platform.os.service.course.cou.packageCou.PackageCourseBiz;
import com.base.cn.platform.os.service.course.mould.CouMouldBiz;
import com.base.cn.platform.os.service.course.open.CourseOpenBiz;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 课程目录Controller接口
 *
 * @author s.li
 * @create 2018-04-26-19:32
 */
@RestController
@RequestMapping("/course")
public class CourseCatalogController extends BaseController {

    @Autowired
    private CourseCatalogBiz courseCatalogBiz;
    @Autowired
    private CouMouldBiz couMouldBiz;
    @Autowired
    private CourseBiz courseBiz;
    @Autowired
    private CourseCommentBiz courseCommentBiz;
    @Autowired
    private CourseOpenBiz courseOpenBiz;
    @Autowired
    private CourseBuyRecordBiz courseBuyRecordBiz;
    @Autowired
    private PackageCourseBiz packageCourseBiz;

    /**
     * 调整节点排序
     * @param currentId 要操作的节点ID
     * @param currentSort 操作的节点的新排序
     * @param oldId 被替换节点的ID
     * @param oldSort 被替换节点的排序
     * @return Map<String,Object>
     */
    @RequestMapping("/updateNodeSort")
    public void updateNodeSort(@RequestParam("currentId") BigDecimal currentId,
                        @RequestParam("currentSort") int currentSort,
                        @RequestParam("oldId") BigDecimal oldId,
                        @RequestParam("oldSort") int oldSort){
        courseCatalogBiz.updateNodeSort(currentId,currentSort,oldId,oldSort);
    }

    /**
     * 查询目录数量
     * @param condition 查询条件
     * @return 数量
     */
    @RequestMapping("/getCourseCatalogCount")
    public BigDecimal getCourseCatalogCount(@RequestBody CourseCatalogCondition condition){
        return courseCatalogBiz.getCourseCatalogCount(condition);
    }

    /**
     * 保存课程目录数据
     *
     * @param courseCatalog 课程对象
     * @return courseCatalog
     */
    @RequestMapping("/saveCourseCatalog")
    public Map<String, Object> saveCourseCatalog(@RequestBody CourseCatalog courseCatalog) {
        /*if (courseCatalog.getNodeType()==2&&(StringUtils.isEmpty(courseCatalog.getMaterialId())||courseCatalog.getMaterialId().compareTo(new BigDecimal(0))==0)) {
            return ResultUtil.ERROR("请选择对应教学资源");
        }*/
        if (StringUtils.isEmpty(courseCatalog.getCatalogName())) {
            return ResultUtil.ERROR("请填写章节名称");
        } else {
            if (courseCatalog.getCatalogName().trim().length() > 30) {
                return ResultUtil.ERROR("章节名称限30个字符以内");
            }
        }
        if (courseCatalogBiz.checkRepeatMaterial(courseCatalog.getCourseId(), courseCatalog.getMaterialId(), courseCatalog.getId())) {
            return ResultUtil.ERROR("该素材已添加到课程目录中");
        }
        courseCatalog = courseCatalogBiz.saveCourseCatalog(courseCatalog);
        return ResultUtil.SUCCESS("目录数据保存成功", courseCatalog);
    }

    /**
     * 给课程添加模块目录
     *
     * @param courseId 课程ID
     * @param mouldIds 模块ID串
     * @return Map<String,Object>
     */
    @RequestMapping("/saveCourseMould")
    public Map<String, Object> saveCourseMould(@RequestParam("courseId") BigDecimal courseId,
                                               @RequestParam("mouldIds") String mouldIds) {
        if (StringUtils.isEmpty(mouldIds)) {
            return ResultUtil.ERROR("请选择模块");
        }
        String message = courseCatalogBiz.checkRepeatMould(courseId, mouldIds);
        if (message != null) {
            return ResultUtil.ERROR(message);
        }
        List<CouMould> mouldList = null;
        if (StringUtils.isNotEmpty(mouldIds)) {
            mouldList = couMouldBiz.findCouMouldByIds(mouldIds, false, false, true);
        }
        //执行保存
        List<CourseCatalog> courseCatalogList = courseCatalogBiz.saveCourseCatalogByMould(courseId, mouldList);
        return ResultUtil.SUCCESS("模块导入成功", courseCatalogList);
    }

    /**
     * 删除目录数据
     *
     * @param ids 目录ID串
     */
    @RequestMapping("/deleteCourseCatalogByIds")
    public Map<String, Object> deleteCourseCatalogByIds(@RequestParam("ids") String ids) {
        courseCatalogBiz.deleteCourseCatalogByIds(ids);
        return ResultUtil.SUCCESS("目录删除成功");
    }

    /**
     * 修改章节父级ID
     *
     * @param id       章节的ID
     * @param parentId 章节新的父级ID
     * @return Map<String,Object>
     */
    @RequestMapping("/updateCourseCatalogParent")
    public Map<String, Object> updateCourseCatalogParent(@RequestParam("id") BigDecimal id,
                                                         @RequestParam("parentId") BigDecimal parentId) {
        courseCatalogBiz.updateCourseCatalogParent(id, parentId);
        return ResultUtil.SUCCESS("归属父级修改成功");
    }

    /**
     * 通过课程ID，查询课程的目录数据列表,并且分层
     *
     * @param buyCourseId     购买课程的ID
     * @param userId        用户ID
     * @param courseId        需要查询目录的课程ID
     * @param setMaterialData 是否设置素材数据
     * @param setLoresetPoint 设置知识点
     * @param setQuestion     设置试题
     * @param group           按题型分组
     * @param setPlayRecord           设置播放记录
     * @return List<CourseCatalog>
     */
    @RequestMapping("/findCourseCatalogLayeredByCourseId")
    public List<CourseCatalog> findCourseCatalogLayeredByCourseId(@RequestParam(value = "buyCourseId",required = false,defaultValue = "0") BigDecimal buyCourseId,
                                                                  @RequestParam("userId") BigDecimal userId,
                                                                  @RequestParam("courseId") BigDecimal courseId,
                                                                  @RequestParam("setMaterialData") boolean setMaterialData,
                                                                  @RequestParam("setLoresetPoint") boolean setLoresetPoint,
                                                                  @RequestParam("setQuestion") boolean setQuestion,
                                                                  @RequestParam("group") boolean group,
                                                                  @RequestParam("setPlayRecord") boolean setPlayRecord) {
        return courseCatalogBiz.findCourseCatalogLayeredByCourseId(buyCourseId,userId,courseId, setMaterialData, setLoresetPoint, setQuestion, group,setPlayRecord);
    }

    /**
     * 通过课程ID，查询课程的目录数据列表
     *
     * @param courseId        设置ID
     * @param setMaterialData 是否设置素材数据
     * @param setLoresetPoint 设置知识点
     * @param setQuestion     设置试题
     * @return List<CourseCatalog>
     */
    @RequestMapping("/findCourseCatalogByCourseId")
    public List<CourseCatalog> findCourseCatalogByCourseId(@RequestParam("courseId") BigDecimal courseId,
                                                           @RequestParam("setMaterialData") boolean setMaterialData,
                                                           @RequestParam("setLoresetPoint") boolean setLoresetPoint,
                                                           @RequestParam("setQuestion") boolean setQuestion,
                                                           @RequestParam("group") boolean group) {
        return courseCatalogBiz.findCourseCatalogByCourseId(courseId, setMaterialData, setLoresetPoint, setQuestion, group);
    }

    /**
     * 通过ID查询目录数据
     *
     * @param id              ID
     * @param setMaterialData 是否设置素材数据
     * @param setLoresetPoint 设置知识点
     * @param setQuestion     设置试题
     * @return CourseCatalog
     */
    @RequestMapping("/findCourseCatalogById")
    public CourseCatalog findCourseCatalogById(@RequestParam("id") BigDecimal id,
                                               @RequestParam("setMaterialData") boolean setMaterialData,
                                               @RequestParam("setLoresetPoint") boolean setLoresetPoint,
                                               @RequestParam("setQuestion") boolean setQuestion,
                                               @RequestParam("group") boolean group) {
        return courseCatalogBiz.findCourseCatalogById(id, setMaterialData, setLoresetPoint, setQuestion, group);
    }

    /**
     * 通过ID串，查询目录数据
     *
     * @param ids             目录ID串
     * @param setMaterialData 是否设置素材数据
     * @param setLoresetPoint 设置知识点
     * @param setQuestion     设置试题
     * @return List<CourseCatalog>
     */
    @RequestMapping("/findCourseCatalogByIds")
    public List<CourseCatalog> findCourseCatalogByIds(@RequestParam("ids") String ids,
                                                      @RequestParam("setMaterialData") boolean setMaterialData,
                                                      @RequestParam("setLoresetPoint") boolean setLoresetPoint,
                                                      @RequestParam("setQuestion") boolean setQuestion,
                                                      @RequestParam("group") boolean group) {
        return courseCatalogBiz.findCourseCatalogByIds(ids, setMaterialData, setLoresetPoint, setQuestion, group);
    }

    /**
     * 多条件查询目录数据
     *
     * @param condition       查询条件对象
     * @param setMaterialData 是否设置素材数据
     * @param setLoresetPoint 设置知识点
     * @param setQuestion     设置试题
     * @return List<CourseCatalog>
     */
    @RequestMapping("/findCourseCatalogList")
    public List<CourseCatalog> findCourseCatalogList(@RequestBody CourseCatalogCondition condition,
                                                     @RequestParam("setMaterialData") boolean setMaterialData,
                                                     @RequestParam("setLoresetPoint") boolean setLoresetPoint,
                                                     @RequestParam("setQuestion") boolean setQuestion,
                                                     @RequestParam("group") boolean group) {
        return courseCatalogBiz.findCourseCatalogList(condition, setMaterialData, setLoresetPoint, setQuestion, group);
    }

    /**
     * 获取最新的目录
     * @param courseIds 课程ID串
     * @return 最新的目录对象
     */
    @RequestMapping("/getNewCourseCatalog")
    public CourseCatalog getNewCourseCatalog(@RequestParam("courseIds") String courseIds){
        CourseCatalog courseCatalog = courseCatalogBiz.findOne(" courseId in ("+courseIds+") and materialId > 0 order by updateTime desc",null);
        if(ObjectUtils.isNotEmpty(courseCatalog)){
            if(DataUtil.idIsNotNull(courseCatalog.getParentId())){
                CourseCatalog parentCatalog = courseCatalogBiz.findById(courseCatalog.getParentId());
                courseCatalog.setParentCatalog(parentCatalog);
            }
            BigDecimal courseId = courseCatalog.getCourseId();
            List<String> columns = new ArrayList<>();
            columns.add("courseName");
            Course course = courseBiz.findOne("id ="+courseId,columns);
            courseCatalog.setCourse(course);
        }
        return courseCatalog;
    }

    /**
     *用于评价导出
     * @param courseId 课程id
     * @param QueryIds 评价id串
     * @return
     */
    @RequestMapping("/findCourseCatalogListExcel")
    public List<CourseCatalog> findCourseCatalogListExcel(@RequestParam("courseId") BigDecimal courseId, @RequestParam(value = "QueryIds", required = false) String QueryIds) {
        CourseCatalogCondition condition = new CourseCatalogCondition();
        condition.setCourseId(courseId);
        condition.setQueryIds(QueryIds);
        return courseCatalogBiz.findCourseCatalogList(condition,false,false,false,false);
    }

    /**
     *  随堂练习下载
     * @param catalogId 章节ID
     * @returnfindCourseCatalogById
     */
    @RequestMapping("/downloadDatum")
    public ResponseEntity<byte[]> downloadDatum(@RequestParam("catalogId") BigDecimal catalogId) throws Exception {
        CourseCatalog courseCatalog = courseCatalogBiz.findCourseCatalogById(catalogId, false, false, false, false);
        List<Map<String, Object>> inputStreamList = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(courseCatalog)){
            List<Map<String, String>> datumList = courseCatalog.getDatumList();
            if(!datumList.isEmpty()){
                datumList.forEach(e->{
                    try {
                        String url = e.get("url");
                        InputStream   inputStream = FileDownloadUtil.getInputStream(url);
                        if(inputStream!=null && inputStream.available() >0){
                            Map<String, Object> datums = new HashMap<>();
                            datums.put("inputStream",inputStream);
                            datums.put("name",e.get("name"));
                            inputStreamList.add(datums);
                        }
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                });

            }
        }
        return   FileDownloadUtil.createRar(inputStreamList,courseCatalog.getCatalogName()+"随堂资料"+System.currentTimeMillis());
    }



    /**
     * 通过课程ID，查询课程的目录数据列表随堂练习
     *
     * @param courseId        设置ID
     * @return List<CourseCatalog>
     */
    @RequestMapping("/findCourseCatalogPracticeByCourseId")
    public List<CourseCatalog> findCourseCatalogPracticeByCourseId(@RequestParam("courseId") BigDecimal courseId,@RequestParam("courseScoreRate") double courseScoreRate) {
        return courseCatalogBiz.findCourseCatalogPracticeByCourseId(courseId,courseScoreRate);
    }
    /**
     * 导出评价
     * @param map
     * @return
     * @throws Exception
     */
    @RequestMapping("/downloadExcelDetailList")
    public ResponseEntity<byte[]> downloadExcelDetailList(@RequestBody Map<String,Object> map) throws Exception {
        StringBuilder filename = new StringBuilder();
        //文件名
        String courseName = getFilename(map);
        map.put("directoryName",courseName);
        filename.append(courseName).append("_").append("评价明细");
     return FileExportImportUtil.exportExcel(getTitles(map.get("type").toString()),getData(map),filename.toString());
    }

    /**
     * 导出的数据
     */
    private List<List<String>> getData(Map<String,Object> param) {

        List<List<String>> data = new ArrayList<>();
        switch (param.get("type").toString()) {
            case "evaluation":

                List<CourseCatalog> courseCommonListExcel = this.findCourseCatalogListExcel(new BigDecimal(param.get("id").toString()), param.get("commentIds").toString());
                courseCommonListExcel.forEach((v) -> {
                    Integer quality=  new Integer(v.getQuality());
                    Integer teach = new Integer(v.getTeach());
                    Integer feel =  new Integer(v.getFeel());
                    Integer total  =  quality+teach+feel;
                    Course course = v.getCourse();
                    data.add(Arrays.asList(
                            v.getId().toString(),
                            param.get("directoryName").toString(),
                            v.getCatalogName(),
                            v.getCommentCount().toString(),
                            total.toString(),
                            quality.toString(),
                            teach.toString(),
                            feel.toString()
                    ));
                });


                break;
            case "evaluationDetails":
                StringBuilder courseName= new StringBuilder();
                List<CourseComment> excelDetailList = courseCommentBiz.ExcelDetailList(param.get("commentIds").toString(), true, true, true,param);
                excelDetailList.forEach((v) -> {
                    Integer quality=  new Integer(v.getQuality());
                    Integer teach = new Integer(v.getTeach());
                    Integer feel =  new Integer(v.getFeel());
                    Map<String, Object> user = v.getUser();
                    CourseCatalog catalog = v.getCatalog();
                    Course course = v.getCourse();
                    Integer total  =  quality+teach+feel;
                    data.add(Arrays.asList(
                            v.getId().toString(),
                            course.getCourseName()+"_"+catalog.getCatalogName(),
                            user.get("nickname") + " " + user.get("mobile") + " " + user.get("email") + "(" + user.get("id") + ")",
                            total.toString(),
                            quality.toString(),
                            teach.toString(),
                            feel.toString(),
                            v.getMultiple().toString(),
                            v.getComment()
                    ));
                });


                break;
        }
        return data;
    }

    private String[] getTitles(String key) {
        switch (key) {
            case "evaluation":
                return   new String[]{"ID","课程名称","章节名称", "评分人数", "累计总分", "课程质量总分", "教学质量总分", "综合感受总分"};
            case "evaluationDetails":
                return new String[]{"ID","课程-章节名称","评分人", "总分", "课程质量", "教学质量", "综合感受","综合评分","反馈内容"};
            default:
                return new String[]{};
        }
    }

    @RequestMapping("/findCourseCatalogPage")
    public List<CourseCatalog> findCourseCatalogPage(@RequestBody CourseCatalog courseCatalog){
//        Pagination page = new Pagination();
//        page.setCurrentPage(currentPage);
//        page.setPageSize(pageSize);
        return courseCatalogBiz.findCourseCatalogPage(courseCatalog);
    }

    /**
     * 查询今日直播条数
     * @param map
     * @return
     */
    @RequestMapping("/queryCurrentCount")
    public Integer queryCurrentCount(@RequestBody Map<String, Object> map) {
        return courseCatalogBiz.queryCurrentCount(map);
    }

    @RequestMapping("/findLiveTime")
    public List<String> findLiveTime(@RequestParam("userId") BigDecimal userId) {
        List<String> timeList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<CourseOpen> courseOpenList = courseOpenBiz.find("status != 3", null, null);
        courseOpenList.stream().forEach(c -> {
            timeList.add(sdf.format(c.getOpenTime()));
        });
        List<CourseBuyRecord> courseBuyRecords = courseBuyRecordBiz.find("userId = " + userId + " and courseStatus = 'SUCCESS'", 0, null);
        String packageIds = courseBuyRecords.parallelStream()
                .filter(courseBuyRecord -> !
                        CourseType.COURSE_TYPE_COLUMNS.equals(courseBuyRecord.getCourseTypeKey()) || CourseType.COURSE_TYPE_PACKAGE.equals(courseBuyRecord.getCourseTypeKey() ))
                .map(courseBuyRecord -> courseBuyRecord.getCourseId().toString()).collect(Collectors.joining(","));

        Stream<String> courseIdTemps= courseBuyRecords.parallelStream()
                .filter(courseBuyRecord -> !CourseType.COURSE_TYPE_COLUMNS.equals(courseBuyRecord.getCourseTypeKey()) || !CourseType.COURSE_TYPE_PACKAGE.equals(courseBuyRecord.getCourseTypeKey()))
                .map(courseBuyRecord -> courseBuyRecord.getCourseId().toString());
        List<PackageCourse> packageCourses = new ArrayList<>(0);
        if (StringUtils.isNotEmpty(packageIds)){
            packageCourses = packageCourseBiz.find("packageId in  (" + packageIds + ")", 0, null);
        }
        //套餐下的课程ID
        Stream<String> packageCourseIds = packageCourses.parallelStream().map(PackageCourse::getCourseId).distinct().map(bigDecimal -> bigDecimal.toString());
        List<String> courseIds= Stream.concat(courseIdTemps, packageCourseIds).distinct().collect(Collectors.toList());
        if (ObjectUtils.isNotEmpty(courseIds)){
            String courseIdsStr = courseIds.stream().map(e -> e).collect(Collectors.joining(","));
            List<CourseCatalog> courseCatalogList = courseCatalogBiz.find("courseId in ("+courseIdsStr+") and materialTypeKey = 'LIVE'",null,null);
            courseCatalogList.stream().forEach(c -> {
                timeList.add(sdf.format(c.getLessonStartTime()));
            });
        }
        return timeList;
    }


    /**
     * 文件名课程名
     * @param param
     * @return
     */
    private String getFilename(Map<String,Object> param) {
        switch (param.get("type").toString()) {
            case "evaluation":
                Course course = courseBiz.findCourseById(true, new BigDecimal(param.get("id").toString()), false, false, false, false, false);
                return course.getCourseName();
            case "evaluationDetails":
                CourseCatalog catalog = null;
                Course courseTo = null;
                if(ObjectUtils.isNotEmpty(param.get("id"))){
                    catalog = courseCatalogBiz.findCourseCatalogById(new BigDecimal(param.get("id").toString()), false, false, false, false);
                    courseTo =  courseBiz.findCourseById(true,catalog.getCourseId(), false, false, false, false, false);
                    return courseTo.getCourseName()+ "-" + catalog.getCatalogName();
                }
                if(ObjectUtils.isNotEmpty(param.get("courseId"))){
                    courseTo =  courseBiz.findCourseById(true,new BigDecimal(param.get("courseId").toString()), false, false, false, false, false);
                    return courseTo.getCourseName();
                }

            default:
                return "";
        }
    }
}
